﻿using Common;
using Common.EF.Controllers;
using Common.Model;
using Common.Utility;
using Common.Utility.AJ;
using Common.Utility.AJ.Extension;
using LiveChartsCore;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;
using Stylet;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Media;

namespace AWSV2.ViewModels
{
    public class WeightStackedBarChartViewModel : Screen
    {

        public DateRangeType DateRange { get; set; }

        public DateRangeType[] AvailableDateRanges { get; set; }

        public string Title { get; set; }

        public ObservableCollection<ChartLegendItem> Legend { get; set; }

        private ISeries[] _series;
        public ISeries[] Series
        {
            get { return _series; }
            set { SetAndNotify(ref _series, value); }
        }

        private Axis[] _xAxes;
        public Axis[] XAxes
        {
            get { return _xAxes; }
            set { SetAndNotify(ref _xAxes, value); }
        }

        private Axis[] _yAxes;
        public Axis[] YAxes
        {
            get { return _yAxes; }
            set { SetAndNotify(ref _yAxes, value); }
        }



        public Func<IEnumerable<Common.Models.WeighingRecord>, DateTime, DateTime, List<object>> XAxesHandle;

        public Func<IEnumerable<Common.Models.WeighingRecord>, object, decimal> JZSumHandle;
        public Func<IEnumerable<Common.Models.WeighingRecord>, object, decimal> PZSumHandle;
        public Func<IEnumerable<Common.Models.WeighingRecord>, object, decimal> MZSumHandle;

        public Func<object, string> LabelFormatHandle;

        private DateTime _start;
        private DateTime _end;

        private static readonly Color _jzColor = Color.FromRgb(80, 77, 166);
        private static readonly Color _pzColor = Color.FromRgb(107, 115, 202);
        private static readonly Color _mzColor = Color.FromRgb(111, 209, 246);

        private decimal _maxAbnormalData;

        public static readonly SolidColorBrush _titleBrush
            = Application.Current.FindResource("MaterialDesignBody") as SolidColorBrush;

        public WeightStackedBarChartViewModel()
        {
            _maxAbnormalData = SettingsHelper
                    .AWSV2Settings.Settings["MaxAbnormalData"].TryGetDecimal(100000m);
            _end = DateTime.Today.AddHours(23).AddMinutes(59).AddSeconds(59);
            DateRange = DateRangeType.FifteenDays;
            AvailableDateRanges = new DateRangeType[] {
                DateRangeType.FifteenDays,
                DateRangeType.OneMonth ,
                DateRangeType.OneYear ,
            };
            LabelFormatHandle = (value) =>
            {
                return value?.ToString();
            };
            JZSumHandle = (source, key) =>
            {
                var date = (DateTime)key;
                return source
                    .Where(p => p.Jzrq.GetValueOrDefault().Date == date)
                    .Sum(p => p.Jz);
            };
            PZSumHandle = (source, key) =>
            {
                var date = (DateTime)key;
                return source
                    .Where(p => p.Jzrq.GetValueOrDefault().Date == date)
                    .Sum(p => p.Pz);
            };
            MZSumHandle = (source, key) =>
            {
                var date = (DateTime)key;
                return source
                    .Where(p => p.Jzrq.GetValueOrDefault().Date == date)
                    .Sum(p => p.Mz);
            };


            XAxesHandle = (source, start, end) =>
            {
                var labels = new List<object>();
                var days = end.Subtract(start).TotalDays;
                for (int i = 0; i < days; i++)
                {
                    labels.Add(start.AddDays(i));
                }
                return labels;
            };
            Legend = new ObservableCollection<ChartLegendItem>
            {
                new ChartLegendItem
                {
                    Title = I18NService.Translate(LangKeys.净重),
                    Color = new SolidColorBrush(_jzColor),
                },
                new ChartLegendItem
                {
                    Title = I18NService.Translate(LangKeys.皮重),
                    Color = new SolidColorBrush(_pzColor),
                },
                new ChartLegendItem
                {
                    Title = I18NService.Translate(LangKeys.毛重),
                    Color = new SolidColorBrush(_mzColor),
                }
            };
        }

        public (DateTime start, DateTime end) ComputeDateRange()
        {
            var today = _end.Date;

            switch (DateRange)
            {
                case DateRangeType.SevenDays:
                    _start = today.AddDays(-6);
                    break;
                case DateRangeType.FifteenDays:
                    _start = today.AddDays(-14);
                    break;
                case DateRangeType.OneMonth:
                    _start = DateUtil.GetFirstDateByDate(today.AddMonths(-1));
                    break;
                case DateRangeType.ThreeMonth:
                    _start = DateUtil.GetFirstDateByDate(today.AddMonths(-3));

                    break;
                case DateRangeType.OneYear:
                    _start = DateUtil.GetFirstDateByDate(today.AddMonths(-12));
                    break;
                default:
                    break;
            }

            return (_start, _end);
        }

        public async void RefreshChart(DateRangeType dateRangeType)
        {
            DateRange = dateRangeType;

            ComputeDateRange();

            using var wrCtrl = new WeighingRecordController();

            var dbSource = await wrCtrl.ChartSummarySource(_start, _end,
                SettingsHelper.AWSV2Settings.Settings["MaxAbnormalData"].TryGetDecimal(10000));

            var source = AJAutoMapperService.Instance().Mapper
                .Map<List<Common.EF.Tables.WeighingRecord>, List<Common.Models.WeighingRecord>>(dbSource);

            var rawLabels = XAxesHandle?.Invoke(source, _start, _end) ?? new List<object>();

            var labels = new List<string>();
            foreach (var item in rawLabels)
            {
                labels.Add(LabelFormatHandle?.Invoke(item));
            }
            var paint = new SolidColorPaint(new SKColor(_titleBrush.Color.R, _titleBrush.Color.G, _titleBrush.Color.B));
            XAxes = new Axis[]
                {
                    new Axis
                    {
                        Labels = labels,
                        Padding = new LiveChartsCore.Drawing.Padding(0),
                        NamePaint = paint,
                        LabelsPaint = paint,
                    }
                };
            YAxes = new Axis[]
            {
                new Axis
                    {
                        NamePaint = paint,
                        LabelsPaint = paint,
                    }
            };

            var jzSValues = new List<decimal>();
            var pzSValues = new List<decimal>();
            var mzSValues = new List<decimal>();


            for (int i = 0; i < rawLabels.Count; i++)
            {
                var key = rawLabels.ElementAtOrDefault(i);
                jzSValues.Add(JZSumHandle?.Invoke(source, key) ?? 0);
                pzSValues.Add(PZSumHandle?.Invoke(source, key) ?? 0);
                mzSValues.Add(MZSumHandle?.Invoke(source, key) ?? 0);
            }

            Series = new ISeries[]
            {
                // 净重
                new StackedColumnSeries<decimal> {
                      Values = jzSValues,
                      Stroke = null,
                      MaxBarWidth = 8,
                      Fill = new SolidColorPaint(new SKColor(_jzColor.R,_jzColor.G,_jzColor.B))
                },
                // 皮重
                new StackedColumnSeries<decimal> {
                      Values = pzSValues,
                      Stroke = null,
                      MaxBarWidth = 8,
                      Fill = new SolidColorPaint(new SKColor(_pzColor.R,_pzColor.G,_pzColor.B))
                },
                // 毛重
                new StackedColumnSeries<decimal> {
                      Values = mzSValues,
                      Stroke = null,
                      MaxBarWidth = 8,
                      Fill = new SolidColorPaint(new SKColor(_mzColor.R,_mzColor.G,_mzColor.B))
                }
            };
        }

    }
}
